package com.mall.user.application.service;

import com.mall.user.domain.model.User;
import com.mall.user.domain.port.in.GetUsersUseCase;
import com.mall.user.domain.port.out.GetUsersPort;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 获取用户应用服务
 * 实现用户查询相关的业务逻辑
 */
@Slf4j
@Service
public class GetUsersService implements GetUsersUseCase {
    
    @Resource
    private GetUsersPort getUsersPort;
    
    @Override
    @Transactional(readOnly = true)
    public List<User> getAllUsers() {
        log.info("开始获取所有用户列表");
        
        try {
            List<User> users = getUsersPort.findAllUsers();
            log.info("成功获取用户列表，共 {} 个用户", users.size());
            return users;
        } catch (Exception e) {
            log.error("获取用户列表失败", e);
            throw new RuntimeException("获取用户列表失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<User> getUsersByNamePattern(String namePattern) {
        log.info("根据用户名模式查询用户: {}", namePattern);
        
        if (namePattern == null || namePattern.trim().isEmpty()) {
            log.warn("用户名模式为空，返回所有用户");
            return getAllUsers();
        }
        
        try {
            List<User> users = getUsersPort.findUsersByNamePattern(namePattern.trim());
            log.info("根据用户名模式 '{}' 查询到 {} 个用户", namePattern, users.size());
            return users;
        } catch (Exception e) {
            log.error("根据用户名模式查询用户失败: {}", namePattern, e);
            throw new RuntimeException("查询用户失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<User> getUsersWithPagination(int page, int size) {
        log.info("分页获取用户列表: page={}, size={}", page, size);
        
        // 参数验证
        if (page < 0) {
            log.warn("页码不能小于0，重置为0");
            page = 0;
        }
        if (size <= 0) {
            log.warn("页面大小必须大于0，重置为10");
            size = 10;
        }
        if (size > 100) {
            log.warn("页面大小不能超过100，重置为100");
            size = 100;
        }
        
        try {
            int offset = page * size;
            List<User> users = getUsersPort.findUsersWithPagination(offset, size);
            log.info("分页查询成功: page={}, size={}, 返回 {} 个用户", page, size, users.size());
            return users;
        } catch (Exception e) {
            log.error("分页获取用户列表失败: page={}, size={}", page, size, e);
            throw new RuntimeException("分页查询用户失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public long getUserCount() {
        log.info("获取用户总数");
        
        try {
            long count = getUsersPort.countUsers();
            log.info("用户总数: {}", count);
            return count;
        } catch (Exception e) {
            log.error("获取用户总数失败", e);
            throw new RuntimeException("获取用户总数失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 根据年龄范围获取用户
     * @param minAge 最小年龄
     * @param maxAge 最大年龄
     * @return 用户列表
     */
    public List<User> getUsersByAgeRange(int minAge, int maxAge) {
        log.info("根据年龄范围查询用户: {}~{}", minAge, maxAge);
        
        // 参数验证
        if (minAge < 0 || maxAge < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
        if (minAge > maxAge) {
            throw new IllegalArgumentException("最小年龄不能大于最大年龄");
        }
        
        try {
            List<User> users = getUsersPort.findUsersByAgeRange(minAge, maxAge);
            log.info("根据年龄范围 {}~{} 查询到 {} 个用户", minAge, maxAge, users.size());
            return users;
        } catch (Exception e) {
            log.error("根据年龄范围查询用户失败: {}~{}", minAge, maxAge, e);
            throw new RuntimeException("根据年龄范围查询用户失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 根据邮箱域名获取用户
     * @param domain 邮箱域名
     * @return 用户列表
     */
    public List<User> getUsersByEmailDomain(String domain) {
        log.info("根据邮箱域名查询用户: {}", domain);
        
        if (domain == null || domain.trim().isEmpty()) {
            throw new IllegalArgumentException("邮箱域名不能为空");
        }
        
        try {
            List<User> users = getUsersPort.findUsersByEmailDomain(domain.trim().toLowerCase());
            log.info("根据邮箱域名 '{}' 查询到 {} 个用户", domain, users.size());
            return users;
        } catch (Exception e) {
            log.error("根据邮箱域名查询用户失败: {}", domain, e);
            throw new RuntimeException("根据邮箱域名查询用户失败: " + e.getMessage(), e);
        }
    }
}